﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using caedisi.Web.Services;
using System.ComponentModel.Composition;
using caedisi.Controller.Interface;
using caedisi.Web.DataModel;
using System.ServiceModel.DomainServices.Client;
using caedisi.Models;

namespace caedisi.Controller
{
    /// <summary>
    /// the controller of all LOVs data   
    public class SetupController
    {        
        private static object syncRoot = new Object();
        private object locker = new object();
        private int serviceCallsCompletedCount;
        private const int totalServiceCalls = 3;

        private CellularAutomataDomainContext _context;
        /// <summary>
        /// Gets the context.
        /// </summary>
        public CellularAutomataDomainContext Context
        {
            get { return _context; }
        }
       

        private static volatile SetupController instance;
        /// <summary>
        /// Gets the instance.
        /// </summary>
        public static SetupController Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (syncRoot)
                    {
                        if (instance == null)
                            instance = new SetupController();
                    }
                }
                return instance;
            }
        }

        
        /// <summary>
        /// Prevents a default instance of the <see cref="SetupController"/> class from being created.
        /// </summary>
        private SetupController()
        {
            _context = new CellularAutomataDomainContext();
        }              

        /// <summary>
        /// Loads all.
        /// </summary>
        /// <param name="LoadCompleted">The load completed.</param>
        public void LoadAllLovs(Action<LovEntities> LoadCompleted)
        {
            LovEntities lovEntities = new LovEntities();
            serviceCallsCompletedCount = 0;

            LoadConfigurations(LoadCompleted, lovEntities);
            LoadCellStateTypes(LoadCompleted, lovEntities);
            LoadNeighbourhoodTypes(LoadCompleted, lovEntities);
         }




        /// <summary>
        /// Loads the cell state types.
        /// </summary>
        void LoadCellStateTypes(Action<LovEntities> LoadCompleted, LovEntities lovEntities)
        {
            EntityQuery<CellStateType> query = _context.GetCellStateTypesQuery();

            _context.Load(
               query,
               loadOperation =>
               {

                   if (loadOperation.HasError)
                   {
                       ;//TODO
                   }
                   else
                   {
                       lovEntities.CellStateTypes = _context.CellStateTypes;
                   }

                   lock (locker)
                       serviceCallsCompletedCount++;

                   //when this is reached, we know that all LOVS have been loaded.
                   if (serviceCallsCompletedCount >= totalServiceCalls)
                   {
                       LoadCompleted(lovEntities);
                   }
               },
               null);
        }

        /// <summary>
        /// Loads the neighbourhood types.
        /// </summary>
        void LoadNeighbourhoodTypes(Action<LovEntities> LoadCompleted, LovEntities lovEntities)
        {
            EntityQuery<NeighbourhoodType> query = _context.GetNeighbourhoodTypesQuery();

            _context.Load(
               query,
               loadOperation =>
               {
                   if (loadOperation.HasError)
                   {
                       ;//TODO
                   }
                   else
                   {
                       lovEntities.NeighbourhoodTypes = _context.NeighbourhoodTypes;
                   }

                   lock (locker)
                       serviceCallsCompletedCount++;

                   //when this is reached, we know that all LOVS have been loaded.
                   if (serviceCallsCompletedCount >= totalServiceCalls)
                   {
                       LoadCompleted(lovEntities);
                   }

               },
               null);
        }

        /// <summary>
        /// Loads the configurations.
        /// </summary>
        void LoadConfigurations(Action<LovEntities> LoadCompleted, LovEntities lovEntities)
        {
            EntityQuery<Configuration> query = _context.GetConfigurationsQuery();

            _context.Load(
               query,
               loadOperation =>
               {
                   if (loadOperation.HasError)
                   {
                       ;//TODO
                   }
                   else
                   {
                       lovEntities.Configurations = _context.Configurations;
                   }

                   lock (locker)
                       serviceCallsCompletedCount++;

                   //when this is reached, we know that all LOVS have been loaded.
                   if (serviceCallsCompletedCount >= totalServiceCalls)
                   {
                       LoadCompleted(lovEntities);
                   }
               },
               null);


        }


        /// <summary>
        /// Saves the specified save completed.
        /// </summary>
        /// <param name="SaveCompleted">The save completed.</param>
        public void Save(Action<bool> SaveCompleted)
        {
            _context.SubmitChanges(
                  submitOperation =>
                  {
                      if (submitOperation.HasError)
                      {
                          ;
                      }
                      SaveCompleted(submitOperation.HasError);
                  },
                  null);
        }

        /// <summary>
        /// Gets a value indicating whether this instance has changes.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance has changes; otherwise, <c>false</c>.
        /// </value>
        public bool HasChanges
        {
            get { return (_context != null ? _context.HasChanges : false); }
        }

        /// <summary>
        /// Rejects the changes.
        /// </summary>
        public void RejectChanges()
        {
            this._context.RejectChanges();
        }
        
    }
}
